package com.libleveldb

import com.libleveldb.exception.LevelDBException

/**
 * Holds a batch write operation. (Something like a transaction.)
 */
interface WriteBatch : Iterable<WriteBatch.Operation?> {
    /**
     * Interface for a WriteBatch operation. LevelDB supports puts and deletions.
     */
    interface Operation {
        /**
         * The key to put or delete.
         *
         * @return the key, never null
         */
        fun key(): ByteArray?

        /**
         * The value to associate with [.key].
         *
         * @return could be <tt>null</tt>, especially if [.isDel] <tt>== true</tt>
         */
        fun value(): ByteArray?

        /**
         * Whether this operation is a put.
         *
         * @return
         */
        val isPut: Boolean

        /**
         * Whether this operation is a delete.
         *
         * @return
         */
        val isDel: Boolean
    }

    /**
     * Put the key-value pair in the database.
     *
     * @param key   the key to write
     * @param value the value to write
     * @return this WriteBatch for chaining
     */
    fun put(key: ByteArray?, value: ByteArray?): WriteBatch?

    /**
     * Delete the key from the database.
     *
     * @param key the key to delete
     * @return this WriteBatch for chaining
     */
    fun del(key: ByteArray?): WriteBatch?

    /**
     * Insert a [com.libleveldb.WriteBatch.Operation] in this WriteBatch.
     *
     * @param operation the operation to insert
     * @return this WriteBatch for chaining
     */
    fun insert(operation: Operation?): WriteBatch?

    /**
     * Get all operations in this WriteBatch.
     *
     * @return never null
     */
    val allOperations: Collection<Operation?>?

    /**
     * Commit this WriteBatch to the database.
     *
     * @param levelDB the [com.libleveldb.implementation.NativeLevelDB] database to write to
     * @param sync    whether this is a synchronous (true) or asynchronous (false) write
     * @throws LevelDBException
     */
    @Throws(LevelDBException::class)
    fun write(levelDB: LevelDB?, sync: Boolean)

    /**
     * Commit this WriteBatch to the database asynchronously.
     *
     * @param levelDB the [com.libleveldb.implementation.NativeLevelDB] database to write to
     * @throws LevelDBException
     */
    @Throws(LevelDBException::class)
    fun write(levelDB: LevelDB?)
}